#pragma once
#include "collection/Collection.hpp"
#include "lang/Exception.h"
#include "yzrutil.h"
#include <optional>
namespace yzrilyzr_collection{
	template<typename E>
	ECLASS(Queue, public Collection<E>){
	public:
	bool add(const E & e)override{
		if(this->offer(e))
			return true;
		else
			throw yzrilyzr_lang::IllegalStateException("Queue full");
	}
	virtual bool offer(const E & e)=0;
	virtual E remove(){
		std::optional<E> x=this->poll();
		if(x != std::nullopt)
			return x.value();
		else
			throw yzrilyzr_lang::NoSuchElementException();
	}
	virtual std::optional<E> poll()noexcept=0;
	virtual E element()const{
		std::optional<E> x=this->peek();
		if(x != std::nullopt)
			return x.value();
		else
			throw yzrilyzr_lang::NoSuchElementException();
	}
	virtual std::optional<E> peek()const noexcept=0;
	void clear()override{
		while(poll() != std::nullopt);
	}
	bool addAll(const Collection<E> &c)override{
		if(c == *this)
			throw yzrilyzr_lang::IllegalArgumentException();
		bool modified=false;
		for(const E & e : c)
			if(add(e))
				modified=true;
		return modified;
	}
	};
}